[IA64] micro optimize __domain_flush_vtlb_track_entry.
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Tue, 17 Oct 2006 20:22:08 +0000 (14:22 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Tue, 17 Oct 2006 20:22:08 +0000 (14:22 -0600)
try to use local purge instead of global purge when possible.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/ia64/xen/vhpt.c
xen/include/asm-ia64/perfc_defn.h

index 7630e57ff9849603cc284ea1ebd01e823170239c..ecc7269a6918f244a3417115170eea9b1a2994e9 100644 (file)
@@ -381,7 +381,8 @@ __domain_flush_vtlb_track_entry(struct domain* d,
        struct vcpu* v;
        int cpu;
        int vcpu;
-
+       int local_purge = 1;
+       
        BUG_ON((vaddr >> VRN_SHIFT) != VRN7);
        /*
         * heuristic:
@@ -414,17 +415,35 @@ __domain_flush_vtlb_track_entry(struct domain* d,
 
                        /* Invalidate VHPT entries.  */
                        vcpu_flush_vhpt_range(v, vaddr, PAGE_SIZE);
+
+                       /*
+                        * current->processor == v->processor
+                        * is racy. we may see old v->processor and
+                        * a new physical processor of v might see old
+                        * vhpt entry and insert tlb.
+                        */
+                       if (v != current)
+                               local_purge = 0;
                }
        } else {
                for_each_cpu_mask(cpu, entry->pcpu_dirty_mask) {
                        /* Invalidate VHPT entries.  */
                        cpu_flush_vhpt_range(cpu, vaddr, PAGE_SIZE);
+
+                       if (d->vcpu[cpu] != current)
+                               local_purge = 0;
                }
        }
-       /* ptc.ga has release semantics. */
 
        /* ptc.ga  */
-       ia64_global_tlb_purge(vaddr, vaddr + PAGE_SIZE, PAGE_SHIFT);
+       if (local_purge) {
+               ia64_ptcl(vaddr, PAGE_SHIFT << 2);
+               perfc_incrc(domain_flush_vtlb_local);
+       } else {
+               /* ptc.ga has release semantics. */
+               ia64_global_tlb_purge(vaddr, vaddr + PAGE_SIZE, PAGE_SHIFT);
+               perfc_incrc(domain_flush_vtlb_global);
+       }
 
        if (swap_rr0) {
                vcpu_set_rr(current, 0, old_rid);
index ff1c2ef44b11b3cb931e11445243bd290d795513..40c0127c07ff6bb04b47cae1220b819f45b0de32 100644 (file)
@@ -115,6 +115,8 @@ PERFCOUNTER_CPU(vcpu_flush_vtlb_all,            "vcpu_flush_vtlb_all")
 PERFCOUNTER_CPU(domain_flush_vtlb_all,          "domain_flush_vtlb_all")
 PERFCOUNTER_CPU(vcpu_flush_tlb_vhpt_range,      "vcpu_flush_tlb_vhpt_range")
 PERFCOUNTER_CPU(domain_flush_vtlb_track_entry,  "domain_flush_vtlb_track_entry")
+PERFCOUNTER_CPU(domain_flush_vtlb_local,        "domain_flush_vtlb_local")
+PERFCOUNTER_CPU(domain_flush_vtlb_global,       "domain_flush_vtlb_global")
 PERFCOUNTER_CPU(domain_flush_vtlb_range,        "domain_flush_vtlb_range")
 
 // domain.c